package wang.lxl.remoteexecute;

import java.lang.reflect.Method;

/**
 * @Author lixilin
 * @Date 2021/4/24 10:23
 * @Description javaclass执行工具
 */
public class JavaclassExecuter {
    /**
     * @param classByte 需要执行的class文件的byte数组
     * @return class文件中 类执行的System.out输出的内容
     */
    public static String execute(byte[] classByte) {
        HackSystem.clearBuffer();
        ClassModifier cm = new ClassModifier(classByte);
        /**
         * 将源class文件的中java.lang.System 替换为我们自己的HackSystem类
         * 替换之后,由于我们自定义的HackSystem中的方法签名和java.lang.System中的方法一样,所有在原本的class中
         * 调用java.lang.System的方法的地方,都会走我们自定义的HackSystem中方法的逻辑了.
         */
        byte[] modifyBytes = cm.modifyUTF8Constant("java/lang/System", "wang/lxl/remoteexecute/HackSystem");
        HotSwapClassLoader loader = new HotSwapClassLoader();
        // 将替换后的class文件加载到虚拟机
        Class clazz = loader.loadByte(modifyBytes);
        try {
            // 反射执行class文件中的main方法
            Method method = clazz.getMethod("main", new Class[]{String[].class});
            method.invoke(null, new String[]{null});
        } catch (Throwable throwable) {
            // 执行出现异常 用HackSystem类输出异常信息
            throwable.printStackTrace(HackSystem.out);
        }
        return HackSystem.getBufferString();
    }
}
